<script setup lang="ts">
import { onMounted, reactive, ref } from 'vue'
import {
  editPictureUsingPost,
  updatePictureUsingPost,
  getPictureVoByIdUsingGet,
  listPictureTagCategoryUsingGet,
  uploadPictureUsingPost,
  uploadPictureByUrlUsingPost,
  uploadPictureByBatchUsingPost,
} from '@/api/pictureController'
import { message } from 'ant-design-vue'
import type { UploadProps } from 'ant-design-vue'
import type { AxiosResponse } from 'axios'
import { useRoute, useRouter } from 'vue-router'
import { PlusOutlined, LoadingOutlined } from '@ant-design/icons-vue'

const route = useRoute()
const router = useRouter()

const picture = ref<API.PictureVO>()
const onSuccess = (newPicture: API.PictureVO) => {
  picture.value = newPicture
  // 填充表单字段
  pictureForm.name = newPicture.name || ''
  pictureForm.introduction = newPicture.introduction
  pictureForm.category = newPicture.category
  pictureForm.tags = newPicture.tags
}

const beforeUpload = (file: NonNullable<UploadProps['fileList']>[number]) => {
  const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png'
  if (!isJpgOrPng) {
    message.error('不支持上传该格式的图片，推荐 jpg 或 png')
  }
  const isLt2M = (file.size ?? 0) / 1024 / 1024 < 2
  if (!isLt2M) {
    message.error('不能上传超过 2M 的图片')
  }
  return isJpgOrPng && isLt2M
}

const loading = ref<boolean>(false)
const fileUrl = ref<string>()

/**
 * 上传
 * @param options
 */
const handleUpload = async (options: { file: File }) => {
  loading.value = true
  try {
    // 判断是否是编辑模式：优先使用 route.query.id，其次使用 picture.value?.id
    // 注意：使用字符串类型避免大数精度丢失
    const editId = route.query?.id
      ? String(route.query.id)
      : picture.value?.id
        ? String(picture.value.id)
        : undefined
    const body: Record<string, string | number> = {}
    const res = (await uploadPictureUsingPost(
      {},
      body,
      options.file,
    )) as AxiosResponse<API.BaseResponsePictureVO_>
    if (res.data.code === 0 && res.data.data) {
      message.success(editId ? '图片替换成功' : '图片上传成功')
      // 设置 picture，触发表单显示
      onSuccess(res.data.data)
    } else {
      message.error('图片上传失败，' + res.data.message)
    }
  } catch (error) {
    console.error('图片上传失败:', error)
    message.error('图片上传失败')
  } finally {
    loading.value = false
  }
}

const pictureForm = reactive<API.PictureEditRequest>({})

/**
 * 提交表单
 * @param values
 */
const handleSubmit = async (values: API.PictureEditRequest) => {
  const pictureId = picture.value?.id
  if (!pictureId) {
    message.error('请先上传图片')
    return
  }

  // 判断是编辑还是新增
  const isEdit = !!route.query?.id
  let res

  if (isEdit) {
    // 编辑模式，使用 update 接口
    res = await updatePictureUsingPost({
      ...values,
      id: pictureId,
    } as API.PictureUpdateRequest)
  } else {
    // 新增模式，使用 edit 接口
    res = await editPictureUsingPost({
      ...values,
      id: pictureId,
    } as API.PictureEditRequest)
  }

  if (res.data.code === 0 && res.data.data) {
    message.success(isEdit ? '更新成功' : '创建成功')
    // 跳转到图片详情页
    router.push({
      path: `/picture/${pictureId}`,
    })
  } else {
    message.error('操作失败，' + res.data.message)
  }
}

const categoryOptions = ref<{ value: string; label: string }[]>([])
const tagOptions = ref<{ value: string; label: string }[]>([])

// 获取标签和分类选项
const getTagCategoryOptions = async () => {
  const res = await listPictureTagCategoryUsingGet()
  if (res.data.code === 0 && res.data.data) {
    // 转换成下拉选项组件接受的格式
    tagOptions.value = (res.data.data.tagList ?? []).map((data: string) => {
      return {
        value: data,
        label: data,
      }
    })
    categoryOptions.value = (res.data.data.categoryList ?? []).map((data: string) => {
      return {
        value: data,
        label: data,
      }
    })
  } else {
    message.error('加载选项失败，' + res.data.message)
  }
}

onMounted(() => {
  getTagCategoryOptions()
})

// 获取老数据
const getOldPicture = async () => {
  // 获取数据
  const id = route.query?.id
  if (id) {
    // 注意：id 作为字符串传递，避免大数精度丢失
    const res = await getPictureVoByIdUsingGet({
      id: id as unknown as number,
    })
    if (res.data.code === 0 && res.data.data) {
      const data = res.data.data
      picture.value = data
      pictureForm.name = data.name
      pictureForm.introduction = data.introduction
      pictureForm.category = data.category
      pictureForm.tags = data.tags
    }
  }
}

onMounted(() => {
  getOldPicture()
})

// 根据路由参数设置上传类型
const uploadType = ref<'file' | 'url' | 'batch'>(route.query?.tab === 'batch' ? 'batch' : 'file')

// 批量创建表单
const batchForm = reactive<API.PictureUploadByBatchRequest>({
  searchText: '',
  count: 10,
  namePrefix: '',
})

// 批量创建加载状态
const batchLoading = ref(false)

/**
 * 处理 URL 上传
 */
const handleUrlUpload = async () => {
  if (!fileUrl.value) {
    message.error('请输入图片 URL')
    return
  }

  loading.value = true
  try {
    // 判断是否是编辑模式
    const editId = route.query?.id
      ? String(route.query.id)
      : picture.value?.id
        ? String(picture.value.id)
        : undefined

    // 调用后端 URL 上传接口
    const res = await uploadPictureByUrlUsingPost({
      fileUrl: fileUrl.value,
      id: editId ? Number(editId) : undefined,
    })

    if (res.data.code === 0 && res.data.data) {
      message.success(editId ? '图片替换成功' : '图片上传成功')
      // 设置 picture，触发表单显示
      onSuccess(res.data.data)
    } else {
      message.error('图片上传失败，' + res.data.message)
    }
  } catch (error) {
    console.error('图片上传失败:', error)
    message.error('图片上传失败')
  } finally {
    loading.value = false
  }
}

/**
 * 处理批量创建
 */
const handleBatchCreate = async () => {
  if (!batchForm.searchText) {
    message.error('请输入关键词')
    return
  }

  if (!batchForm.count || batchForm.count <= 0) {
    message.error('请输入有效的抓取数量')
    return
  }

  batchLoading.value = true
  try {
    const res = await uploadPictureByBatchUsingPost({
      searchText: batchForm.searchText,
      count: batchForm.count,
      namePrefix: batchForm.namePrefix,
    })

    if (res.data.code === 0) {
      message.success(`成功创建 ${res.data.data} 张图片`)
      // 跳转到主页
      setTimeout(() => {
        router.push('/')
      }, 1500)
    } else {
      message.error('批量创建失败，' + res.data.message)
    }
  } catch (error) {
    console.error('批量创建失败:', error)
    message.error('批量创建失败')
  } finally {
    batchLoading.value = false
  }
}
</script>

<template>
  <div id="addPicturePage">
    <h2 style="margin-bottom: 16px">
      {{
        route.query?.tab === 'batch' ? '批量创建图片' : route.query?.id ? '修改图片' : '创建图片'
      }}
    </h2>

    <!-- 选择上传方式 -->
    <a-tabs v-model:activeKey="uploadType">
      <a-tab-pane key="file" tab="文件上传">
        <!-- 图片上传区域 -->
        <div class="picture-upload" style="margin-bottom: 24px">
          <a-alert
            v-if="route.query?.id && picture"
            message="编辑模式：点击图片可以替换"
            type="info"
            show-icon
            style="margin-bottom: 16px"
          />
          <a-upload
            list-type="picture-card"
            :show-upload-list="false"
            :custom-request="handleUpload"
            :before-upload="beforeUpload"
          >
            <img v-if="picture?.url" :src="picture?.url" alt="avatar" />
            <div v-else>
              <loading-outlined v-if="loading"></loading-outlined>
              <plus-outlined v-else></plus-outlined>
              <div class="ant-upload-text">点击或拖拽上传图片</div>
            </div>
          </a-upload>
        </div>
      </a-tab-pane>
      <a-tab-pane key="url" tab="URL 上传" force-render>
        <div class="url-picture-upload">
          <a-input-group compact style="margin-bottom: 16px">
            <a-input
              v-model:value="fileUrl"
              style="width: calc(100% - 120px)"
              placeholder="请输入图片 URL"
            />
            <a-button
              type="primary"
              :loading="loading"
              @click="handleUrlUpload"
              style="width: 120px"
              >提交</a-button
            >
          </a-input-group>
          <div v-if="picture?.url" style="margin-top: 16px">
            <img :src="picture?.url" alt="avatar" style="max-width: 100%; max-height: 480px" />
          </div>
        </div>
      </a-tab-pane>
      <a-tab-pane key="batch" tab="批量创建图片" force-render>
        <div class="batch-create-form">
          <a-form layout="vertical" :model="batchForm">
            <a-form-item label="关键词" required>
              <a-input
                v-model:value="batchForm.searchText"
                placeholder="请输入关键词"
                allow-clear
              />
            </a-form-item>
            <a-form-item label="抓取数量" required>
              <a-input-number
                v-model:value="batchForm.count"
                :min="1"
                :max="100"
                style="width: 100%"
                placeholder="请输入抓取数量"
              />
            </a-form-item>
            <a-form-item label="名称前缀">
              <a-input
                v-model:value="batchForm.namePrefix"
                placeholder="请输入名称前缀，会自动补充序号"
                allow-clear
              />
            </a-form-item>
            <a-form-item>
              <a-button
                type="primary"
                size="large"
                :loading="batchLoading"
                @click="handleBatchCreate"
                style="width: 100%"
              >
                执行任务
              </a-button>
            </a-form-item>
          </a-form>
        </div>
      </a-tab-pane>
    </a-tabs>

    <!-- 图片信息表单 -->
    <a-form v-if="picture" layout="vertical" :model="pictureForm" @finish="handleSubmit">
      <a-form-item label="名称" name="name">
        <a-input v-model:value="pictureForm.name" placeholder="请输入名称" />
      </a-form-item>
      <a-form-item label="简介" name="introduction">
        <a-textarea
          v-model:value="pictureForm.introduction"
          placeholder="请输入简介"
          :rows="2"
          autoSize
          allowClear
        />
      </a-form-item>
      <a-form-item label="分类" name="category">
        <a-auto-complete
          v-model:value="pictureForm.category"
          :options="categoryOptions"
          placeholder="请输入分类"
          allowClear
        />
      </a-form-item>
      <a-form-item label="标签" name="tags">
        <a-select
          v-model:value="pictureForm.tags"
          mode="tags"
          :options="tagOptions"
          placeholder="请输入标签"
          allowClear
        />
      </a-form-item>
      <a-form-item>
        <a-button type="primary" html-type="submit" style="width: 100%">
          {{ route.query?.id ? '更新' : '创建' }}
        </a-button>
      </a-form-item>
    </a-form>
  </div>
</template>

<style scoped>
.picture-upload :deep(.ant-upload) {
  width: 100% !important;
  height: 100% !important;
  min-height: 152px;
  min-width: 152px;
}

.picture-upload img {
  max-width: 100%;
  max-height: 480px;
}

.ant-upload-select-picture-card i {
  font-size: 32px;
  color: #999;
}

.ant-upload-select-picture-card .ant-upload-text {
  margin-top: 8px;
  color: #666;
}

#addPicturePage {
  max-width: 720px;
  margin: 0 auto;
}
</style>
